package com.hh.adapters;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.Checkable;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.hh.clientdatatable.ClientDataTable;
import com.hh.clientdatatable.ClientDataTable.CDTStatus;
import com.hh.clientdatatable.TCell;
import com.hh.clientdatatable.TCell.ValueType;
import com.hh.droid.R;
import com.hh.features.PfKeyboard;
import com.hh.listeners.OnNotifyDataSetChangedListener;
import com.hh.ui.UiUtility;

public class CDTListAdapter extends BaseAdapter implements OnNotifyDataSetChangedListener{

	public static final int FLAG_DEFAULT = 0x00;
	public static final int FLAG_AUTO_REQUERY = 0x01;

	
	protected ClientDataTable mClientDataTable;
	protected Context mContext;
	private int mLayoutRow;
	private LayoutInflater mInflater;
	private ViewHolder _mHolder;
	private View _mConvertView;
	private ArrayList<String> _mListOfTags;
	private boolean _mIsEnableAutoNotifyDataSetChanged;
	private  boolean _mAutoRequery;
	private boolean _mIsEnableOnClickWidget;
	private boolean _mFirstBuild;

	public CDTListAdapter(Context pContext,int pLayoutRow,ClientDataTable pCDT){

		mClientDataTable=pCDT;
		mContext=pContext;
		mLayoutRow=pLayoutRow;
		mInflater=(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mClientDataTable.setOnNotifyDataSetChangedListener(this);
		
		View convertView=mInflater.inflate(pLayoutRow, null);
		_mListOfTags=ViewHolder.getAllLayoutTags(convertView);
		_mIsEnableAutoNotifyDataSetChanged=false;
		_mAutoRequery=false;
		_mIsEnableOnClickWidget=true;
		_mFirstBuild=true;
	}

	public void setEnableOnClickWidget(boolean pIsEnabled){
		_mIsEnableOnClickWidget=pIsEnabled;
	}
	public ClientDataTable getClientDataTable() {
		return mClientDataTable;
	}

	public void setClientDataTable(ClientDataTable mClientDataTable) {
		this.mClientDataTable = mClientDataTable;
		mClientDataTable.setOnNotifyDataSetChangedListener(this);
	}

	public void setEnableAutoNotifyDataSetChanged(boolean pIsEnabled,int pFLAG){
		_mIsEnableAutoNotifyDataSetChanged=pIsEnabled;
		if(pFLAG==FLAG_AUTO_REQUERY)
			_mAutoRequery=true;
	}
	
	@Override
	protected void finalize() throws Throwable {
		mContext=null;
		super.finalize();
	}
	@Override
	public int getCount() {
		return mClientDataTable.getRowsCount();
	}

	@Override
	public Object getItem(int position) {
		if (mClientDataTable.moveToPosition(position))
			return mClientDataTable;
		return null;
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	public void clear(){
		mClientDataTable.clear();
		notifyDataSetChanged();
	}
	
	@Override
	public void notifyDataSetChanged() {
		super.notifyDataSetChanged();
	}
	
	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {

		View lWidget=null;
		int lNbrTags=0;
		if(convertView==null){
			
			if(_mFirstBuild){
			if(parent instanceof ListView)
				((ListView)parent).setCacheColorHint(Color.TRANSPARENT);
			_mFirstBuild=false;
			}
			
			convertView = mInflater.inflate(mLayoutRow, parent, false);
			_mConvertView=convertView;
			_mHolder=new ViewHolder();			
			
			lNbrTags=_mListOfTags.size();

			for (int i = 0; i < lNbrTags; i++) {

				lWidget=convertView.findViewWithTag(_mListOfTags.get(i));
				if (lWidget!=null){

					int lColumnIndex=mClientDataTable.indexOfColumn(_mListOfTags.get(i));

					if(mClientDataTable.indexOfColumn(_mListOfTags.get(i))!=-1)
						_mHolder.mSparseArrayHolderViews.put(lColumnIndex,lWidget);
					else
						_mHolder.mSparseArrayHolderViewsNotInCDT.put(lColumnIndex,lWidget);

					convertView.setBackgroundResource(R.drawable.selector_row);

					if(_mIsEnableOnClickWidget){
						if(lWidget instanceof ImageView)
							lWidget.setBackgroundResource(R.drawable.selector_row);

						if(lWidget instanceof TextView ==false)
							lWidget.setOnClickListener(new onClickWidgetListener(convertView));
					}
					convertView.setOnClickListener(new onClickRowListener(convertView));
					convertView.setOnCreateContextMenuListener(new onCreateRowContextMenuListener(convertView));

					if (lWidget instanceof CheckBox){
						CheckBox lCheckBox = (CheckBox) lWidget;
						lCheckBox.setOnCheckedChangeListener(new onCheckedRowChangeListener(convertView,_mListOfTags.get(i)));
					}
					if (lWidget instanceof TextView){
						TextView lTextView = (TextView) lWidget;
						lTextView.setOnFocusChangeListener(new onFocusedRowChangeListener(convertView, _mListOfTags.get(i)));
					}
				}				
			}
			convertView.setTag(R.id.TAG_HOLDER,_mHolder);
		}else{
			_mHolder=(ViewHolder) convertView.getTag(R.id.TAG_HOLDER);
		}
		convertView.setTag(R.id.TAG_POSITION,position);
		int lCurrentCDTPos=mClientDataTable.getPosition();
		bindData(convertView, lWidget, position);
		mClientDataTable.moveToPosition(lCurrentCDTPos);

		return convertView;
	}
	
	private void bindData(View convertView,View lWidget,int position){

		if(getItem(position)!=null){
 
			int lListHolderSize=_mHolder.mSparseArrayHolderViews.size();
			for(int i=0;i<lListHolderSize;i++) {

				int lColumnIndex = _mHolder.mSparseArrayHolderViews.keyAt(i);
				lWidget = _mHolder.mSparseArrayHolderViews.get(lColumnIndex);

				if(lWidget!=null){		 	
					
					final TCell data = mClientDataTable.getCell(position,lColumnIndex);
					if (lWidget instanceof Checkable) {

						((Checkable) lWidget).setChecked(data.asBoolean());
					} else if (lWidget instanceof TextView) {

						((TextView) lWidget).setText(data.asString());
					} else if (lWidget instanceof ImageView) {
						if (data.getValueType()==ValueType.INTEGER) {
							((ImageView) lWidget).setImageResource(data.asInteger());                           
						} else {
							if(!data.asString().equals(""))
								setViewImage((ImageView) lWidget, data.asString());
							else
								((ImageView) lWidget).setImageDrawable(null);
						}
					} else 
						throw new IllegalStateException(lWidget.getClass().getName() + " is not a " +
								" view that can be bounds by this SimpleAdapter");
					
					onIteratedRow(convertView,lWidget,position);
				}
			}
			int lListHolderSizeNotInCDT=_mHolder.mSparseArrayHolderViewsNotInCDT.size();
			for(int i=0;i<lListHolderSizeNotInCDT;i++) {
				int lColumnIndex = _mHolder.mSparseArrayHolderViewsNotInCDT.keyAt(i);
				lWidget = _mHolder.mSparseArrayHolderViewsNotInCDT.get(lColumnIndex);

				if(lWidget!=null){ 		
					onIteratedRow(convertView,lWidget,position);
				}
			}
		}
	}
	public void setViewImage(ImageView v, String value) {
		try {
			v.setImageResource(Integer.parseInt(value));
		} catch (NumberFormatException nfe) {
			v.setImageURI(Uri.parse(value));
		}
	}
	
	public void validateEditTextChanges(){
		UiUtility.clearAllChildrensFocus((ViewGroup)_mConvertView);
		mClientDataTable.edit();
		PfKeyboard.hide(mContext, _mConvertView);
	}
	
	/**
	 * override this method when we need to access to CDT content 
	 * for each row when iterate all the data
	 * @param row :row (convertView)
	 * @param widget : Button , TextView etc...
	 * @param position : position of row
	 */
	protected  void onIteratedRow(View row,View widget,int position){};
	
	/**
	 * override this method to capture the click on selected row 
	 * @param row
	 * @param position : position of selected row
	 */
	protected  void onClickRow(View row,int position){};
	
	/**
	 * override this method to capture the click on selected widget (Button, ImageView ...) inside a row 
	 * @param tagWidget : the tag of the selected widget
	 * @param position : the position of row of selected widget
	 */
	
	protected  void onClickWidget(String tagWidget,int position){};

	/**
	 * override this method to capture the Long click on selected Row,
	 * and we can create context Menu inside this method 
	 * @param row : selected row
	 * @param menu : for create a context menu
	 * @param position : position of selected row
	 */
	protected  void onLongClickRow(View row,Menu menu,int position){};
	
	/**
	 * Onclick Listener for each row
	 * @author WajdiHh
	 *
	 */
	class onClickRowListener implements OnClickListener{

		private View _mRow;
		public onClickRowListener(View pRow){
			_mRow=pRow;
		}
		@Override
		public void onClick(View v) {
			int lCurrentPos=(Integer) _mRow.getTag(R.id.TAG_POSITION);
			getItem(lCurrentPos);
			onClickRow(_mRow,lCurrentPos);
		}		
	}
	/**
	 * Onclick Listener for each widget on the row
	 * @author WajdiHh
	 *
	 */
	class onClickWidgetListener implements OnClickListener{

		private View _mRow;
		public onClickWidgetListener(View pRow){
			_mRow=pRow;
		}
		@Override
		public void onClick(View v) {
			int lCurrentPos=(Integer) _mRow.getTag(R.id.TAG_POSITION);
			getItem(lCurrentPos);
			String lTag="";
			if(v.getTag()!=null)
				lTag=v.getTag().toString();

			onClickWidget(lTag, lCurrentPos);			
		}		
	}
	/**
	 * onCheckedRowChangeListener to change status of Chekbox for each row
	 * @author WajdiHh
	  *
	  */
	 class onCheckedRowChangeListener implements OnCheckedChangeListener{
		 private View _mRow;
		 private String _mColumnName;
		 
		 public onCheckedRowChangeListener(View pRow,String pColumnName){
			 _mRow=pRow;
			 _mColumnName=pColumnName;
		 }

		 @Override
		 public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
			 int lCurrentPos=(Integer) _mRow.getTag(R.id.TAG_POSITION);
			 getItem(lCurrentPos);

			 if(mClientDataTable.isConnectedToDB()){	

				 if(mClientDataTable.getCDTStatus()==CDTStatus.INSERT)
					 mClientDataTable.cellByName(_mColumnName).insertIntoDB(isChecked);

				 else if(mClientDataTable.getCDTStatus()==CDTStatus.UPDATE)
					 mClientDataTable.cellByName(_mColumnName).updateFromDB(isChecked);

				 else if(mClientDataTable.getCDTStatus()==CDTStatus.DEFAULT)
					 mClientDataTable.cellByName(_mColumnName).setValue(isChecked);
			 }else
				 mClientDataTable.cellByName(_mColumnName).setValue(isChecked);
		 }	
	 }
	 /**
	  * onCheckedRowChangeListener to change status of Checkbox for each row
	  * @author WajdiHh
	  *
	  */
	 class onFocusedRowChangeListener implements OnFocusChangeListener{
		 private View _mRow;
		 private String _mColumnName;
		 
		 public onFocusedRowChangeListener(View pRow,String pColumnName){
			 _mRow=pRow;
			 _mColumnName=pColumnName;
		 }

		 @Override
		 public void onFocusChange(View v, boolean hasFocus) {
			 int lCurrentPos=(Integer) _mRow.getTag(R.id.TAG_POSITION);
			 TextView lTextView=(TextView) v;
			 getItem(lCurrentPos);
			 
			 if(mClientDataTable.isConnectedToDB()){	

				 if(mClientDataTable.getCDTStatus()==CDTStatus.INSERT)
					 mClientDataTable.cellByName(_mColumnName).insertIntoDB(lTextView.getText().toString());

				 else if(mClientDataTable.getCDTStatus()==CDTStatus.UPDATE)
					 mClientDataTable.cellByName(_mColumnName).updateFromDB(lTextView.getText().toString());

				 else if(mClientDataTable.getCDTStatus()==CDTStatus.DEFAULT)
					 mClientDataTable.cellByName(_mColumnName).setValue(lTextView.getText().toString());
			 }else
				 mClientDataTable.cellByName(_mColumnName).setValue(lTextView.getText().toString());		
		 }	
	 }
	 /**
	  * Create a contextMenu for eachRow or get the longClick event 
	  * @author WajdiHh
	  *
	  */
	 class onCreateRowContextMenuListener implements OnCreateContextMenuListener{
		 private View _mRow;

		 public onCreateRowContextMenuListener(View pRow){
			 _mRow=pRow;
		 }
		 @Override
		 public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
			 int lCurrentPos=(Integer) _mRow.getTag(R.id.TAG_POSITION);
			 getItem(lCurrentPos);
			 onLongClickRow(_mRow,menu,lCurrentPos);		
		}		
	 }

	@Override
	public void notifyValueChanged() {	
		
		if(_mAutoRequery)
			mClientDataTable.requery();
		
		if(_mIsEnableAutoNotifyDataSetChanged)
			notifyDataSetChanged();
		
	}
}